package com.ncepu.thumb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ncepu.thumb.constant.ThumbConstant;
import com.ncepu.thumb.exception.BusinessException;
import com.ncepu.thumb.exception.ErrorCode;
import com.ncepu.thumb.model.dto.AddBlogRequest;
import com.ncepu.thumb.model.entity.Blog;
import com.ncepu.thumb.model.entity.User;
import com.ncepu.thumb.model.vo.BlogVO;
import com.ncepu.thumb.service.BlogService;
import com.ncepu.thumb.mapper.BlogMapper;
import com.ncepu.thumb.service.ThumbService;
import com.ncepu.thumb.service.UserService;
import com.ncepu.thumb.utils.RedisKeyUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;

/**
 * @author 14563
 * @description 针对表【blog】的数据库操作Service实现
 * @createDate 2025-05-10 21:18:20
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog>
        implements BlogService {

    @Resource
    private UserService userService;
    @Resource
    @Lazy
    private ThumbService thumbService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private TransactionTemplate transactionTemplate;


    @Override
    public BlogVO getBlogVOById(long blogId, HttpServletRequest request) {
        Blog blog = this.getById(blogId);
        User loginUser = userService.getLoginUser(request);
        return this.getBlogVO(blog, loginUser);
    }

    @Override
    public List<BlogVO> getBlogVOList(List<Blog> blogList, HttpServletRequest request) {

        User loginUser = userService.getLoginUser(request);
        Map<Long, Boolean> blogHasThumbMap = new HashMap<>();
        // 如果用户已登录，先查用户点赞的博客，方便返回列表时设置是否已经点赞
        if (ObjUtil.isNotEmpty(loginUser)) {
//            List<Object> blogIdList = blogList.stream().map(Blog::getId).collect(Collectors.toList());
//            List<Thumb> thumbList = thumbService.lambdaQuery()
//                    .eq(Thumb::getUserId, loginUser.getId())
//                    .in(Thumb::getBlogId, blogSet) // 感觉这一句有点多余
//                    .list();
            Set<Object> thumbSet = redisTemplate.opsForZSet().range(ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId(), 0, -1);
//            List<Object> thumbList = redisTemplate.opsForHash().multiGet(ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId(), blogIdList);
            thumbSet.forEach(thumb -> {
                blogHasThumbMap.put(Long.valueOf(thumb.toString()), true);
            });
//            for(int i = 0; i < thumbList.size(); i++) {
//                if (thumbList.get(i) == null) {
//                    continue;
//                }
//                blogHasThumbMap.put(Long.valueOf(thumbList.get(i).toString()), true);
        }
       // 返回所有博客列表
        return blogList.stream()
                .map(blog -> {
                    BlogVO blogVO = BeanUtil.copyProperties(blog, BlogVO.class);
                    blogVO.setHasThumb(blogHasThumbMap.get(blog.getId()));
                    return blogVO;
                })
                .toList();
    }

    @Override
    public Boolean addBlog(AddBlogRequest addBlogRequest, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if(loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
        }
        String title = addBlogRequest.getTitle();
        String coverImg = addBlogRequest.getCoverImg();
        String content = addBlogRequest.getContent();
        Blog blog = new Blog();
        blog.setUserId(loginUser.getId());
        blog.setTitle(title);
        blog.setCoverImg(coverImg);
        blog.setContent(content);
        return transactionTemplate.execute(status -> {
            boolean save = this.save(blog);
            if(!save) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加博客失败");
            }
            Long id = blog.getId();
            try{
                String blogsExistedKey = RedisKeyUtil.getBlogsExistedKey();
                Long add = redisTemplate.opsForSet().add(blogsExistedKey, id);
                if(add == null || add == 0) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加博客失败");
                }
            }catch (Exception e) {
                status.setRollbackOnly();
                return false;
            }
            return true;
        });

    }

    private BlogVO getBlogVO(Blog blog, User loginUser) {
        BlogVO blogVO = new BlogVO();
        BeanUtil.copyProperties(blog, blogVO);
        // 如果用户未登录，则不需要判断博客是否点赞
        if (loginUser == null) {
            return blogVO;
        }

//        Thumb thumb = thumbService.lambdaQuery()
//                .eq(Thumb::getUserId, loginUser.getId())
//                .eq(Thumb::getBlogId, blog.getId())
//                .one();
//        blogVO.setHasThumb(thumb != null);
        Boolean exist = thumbService.hasThumb(blog.getId(), loginUser.getId());
        blogVO.setHasThumb(exist);

        return blogVO;
    }
}




